package com.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.constant.GoodsConstant;
import com.common.domain.entity.*;
import com.common.domain.vo.ExchangeLogVo;
import com.common.domain.vo.PageVo;
import com.common.domain.vo.PointVo;
import com.common.domain.vo.RoleVo;
import com.common.enums.AppHttpCodeEnum;
import com.common.mapper.ExchangeLogMapper;
import com.common.mapper.GoodsMapper;
import com.common.mapper.PointMapper;
import com.common.service.GoodsService;
import com.common.service.PointService;
import com.common.util.BeanCopyUtils;
import com.common.util.RedisCache;
import com.common.util.SecurityUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.Transient;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author pc
* @description 针对表【sys_point】的数据库操作Service实现
* @createDate 2023-09-02 11:17:55
*/
@Service
public class PointServiceImpl extends ServiceImpl<PointMapper, Point>
implements PointService {
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private PointMapper pointMapper;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private ExchangeLogMapper exchangeLogMapper;

    @Override
    public ResponseResult getUserPointInfo() {
        //获取当前用户id
        Long userId = SecurityUtils.getUserId();
        //得到用户剩余积分
        Long userPoint = pointMapper.getUserPointById(userId);
        return ResponseResult.okResult(userPoint);
    }

    @Override
    public ResponseResult addUserPointLog(Point point) {
        if(save(point)){
            return ResponseResult.okResult();
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.COMMENT_NOT_NULL);
    }

    @Override
    @Transactional
    public ResponseResult exchange(Long goodsId) {
        //校验是否有其他请求
        String userKey = SecurityUtils.getUserId() + "_exchange";
        if(redisCache.exists(userKey)){
            return new ResponseResult().ok(AppHttpCodeEnum.OTHER_REQUESTS_ERROR);
        }
        Goods goodsInfo = goodsService.getGoodsInfo(goodsId);
        if(goodsInfo == null){
            return new ResponseResult().ok(AppHttpCodeEnum.GOODS_ERROR);
        }
        Long userPoint = pointMapper.getUserPointById(SecurityUtils.getUserId());
        if(userPoint < goodsInfo.getGoodsPoint()){
            return new ResponseResult().error(-101,"用户的积分值不足以兑换当前产品");
        }
        try{
            //添加请求
            redisCache.set(userKey, 1, 10L);
            String shopKey = goodsId + "_count";
            Long count = 0L;
            if(redisCache.exists(shopKey)){
                count = goodsInfo.getGoodsNumber() - Long.parseLong(redisCache.getCacheObject(shopKey).toString());
            }else{
                Long exchangeCount = exchangeLogMapper.getExchangeCount(goodsId);
                redisCache.set(shopKey, exchangeCount, 600L);
                count = goodsInfo.getGoodsNumber() - exchangeCount;
            }
            //获取商品剩余数量
            if(count < 0){
                return new ResponseResult().error(-102,"该商品已经全部兑换，请选择其他商品进行兑换");
            }
            //记录用户积分
            Point point = new Point();
            point.setUserId(SecurityUtils.getUserId());
            point.setScore(-goodsInfo.getGoodsPoint());
            point.setScoreDetail("兑换商品");
            point.setType(GoodsConstant.SUB_POINT);
            save(point);
            //添加兑换记录
            ExchangeLog exchangeLog = new ExchangeLog();
            exchangeLog.setGoodsId(goodsId);
            exchangeLog.setUserId(SecurityUtils.getUserId());
            exchangeLog.setReceiveFlag(GoodsConstant.UN_RECEIVED);
            exchangeLogMapper.insert(exchangeLog);
            //添加
            redisCache.incrBy(shopKey);
            return new ResponseResult().ok("兑换商品成功");
        }catch (Exception e){
            //删除缓存
            return new ResponseResult().ok("兑换商品失败，请稍后再试");
        }finally {
            //删除缓存
            redisCache.remove(userKey);
        }
    }

    @Override
    public ResponseResult getUserPointDetail(Long pageNum, Long pageSize) {
        LambdaQueryWrapper<Point> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(Point::getUserId, SecurityUtils.getUserId());

        queryWrapper.orderByDesc(Point::getCreateTime);

        Page<Point> page = new Page<>();
        page.setCurrent(pageNum);
        page.setSize(pageSize);

        page(page, queryWrapper);

        List<PointVo> pointVoList = BeanCopyUtils.copyBeanList(page.getRecords(), PointVo.class);
        PageVo pageVo = new PageVo(pointVoList, page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult allPointList(Integer pageNum, Integer pageSize, String userName, String type) {
        PageHelper.startPage(pageNum,pageSize);

        List<PointVo> list =  pointMapper.allPointList(userName,type);

        PageInfo<PointVo> pageInfo = new PageInfo<>(list);

        pageInfo.setList(list);

        return ResponseResult.okResult(pageInfo);
    }

    @Override
    public ResponseResult insertPoint(Point point) {
        save(point);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteRole(String ids) {
        String[] split = ids.split(",");
        removeByIds(Arrays.asList(split));
        return ResponseResult.okResult();
    }

}
